/**
 * Created with IntelliJ IDEA.
 * User: zzl
 * Date: 12-11-30
 * To change this template use File | Settings | File Templates.
 */
/**
 *   api month range: (1-12)
 */
(function ($, undefined) {

    var monthAbbrs = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'];

    var DatetimePicker = function (container, options) {
        this.$container = $(container);
        this.options = options;

        var date = options.date;
        if (!date) {
            var now = new Date();
            var year = parseInt(options.year) || now.getYear();
            var month = now.getMonth();
            if ('month' in options) {
                month = parseInt(options.month) - 1;
            }
            var day = parseInt(options.day) || 1;
            date = new Date(year, month, day);
//            if ('day' in options) {
            this.selectedDate = date;
//            }
        }
        else {
            this.selectedDate = date;
        }
        this.date = date;

        this.setup();
    };

    var proto = { constructor: DatetimePicker };
    DatetimePicker.prototype = proto;

    proto.setup = function () {
        var me = this;

        me.$table = me.$container.find('.calendar');
        me.$txtMonth = me.$container.find('.txtMonth');
        me.$txtYear = me.$container.find('.txtYear');

        //
        me.$txtMonth.on('mousedown', function (e) {
            me.onTxtMonthMouseDown(e);
        });
        me.$txtMonth.on('blur', function (e) {
            me.onTxtMonthBlur(e);
        });
        me.$txtMonth.on('keypress', function (e) {
            if (e.keyCode == 13) {
                me.onTxtMonthBlur(e);
                me.$txtMonth.selectGrid('hide');
            }
        });
        me.$txtMonth.on('focus', function (e) {
            $(this).select().addClass('editor');
        });

        //
        me.$txtYear.on('mousedown', function (e) {
            me.onTxtYearMouseDown(e);
        });
        me.$txtYear.on('blur', function (e) {
            me.onTxtYearBlur(e);
        });
        me.$txtYear.on('keypress', function (e) {
            if (e.keyCode == 13) {
                me.onTxtYearBlur(e);
                me.$txtYear.selectGrid('hide');
            }
        });
        me.$txtYear.on('focus', function (e) {
            $(this).select().addClass('editor');
        });

        //
        me.$container.find('.prevYear').on('click', function (e) {
            me.showMonth(me.showingMonth.getFullYear() - 1, me.showingMonth.getMonth());
            return false;
        });
        me.$container.find('.nextYear').on('click', function (e) {
            me.showMonth(me.showingMonth.getFullYear() + 1, me.showingMonth.getMonth());
            return false;
        });
        me.$container.find('.prevMonth').on('click', function (e) {
            me.showMonth(me.showingMonth.getFullYear(), me.showingMonth.getMonth() - 1);
            return false;
        });
        me.$container.find('.nextMonth').on('click', function (e) {
            me.showMonth(me.showingMonth.getFullYear(), me.showingMonth.getMonth() + 1);
            return false;
        });
        me.$container.find('.btnToday').on('click', function (e) {
            me.btnToday_click(e);
            return false;
        });

        //
        me.$table.find('tbody.days').on('click', 'td', function (e) {
            me.onDayClick($(this));
        });

        me.showMonth(me.date.getFullYear(), me.date.getMonth());

        //
        if (me.options.precision == 'day') {
            me.$container.find('.timePickerContainer').hide();
        }
        else {
            me.$timePicker = me.$container.find('.timePicker');
            me.$timePicker.timePicker({
                precision: me.options.precision
            });
        }
    };

    proto.btnToday_click = function (e) {
        var me = this;
        var now = new Date();
        me.selectedDate = now;//new Date(now.getFullYear(), now.getMonth(), now.getDate());
        if (me.$timePicker) {
            me.$timePicker.timePicker('setValue', now);
        }
        me.showMonth(now.getFullYear(), now.getMonth());
    };

    //
    proto.onTxtMonthBlur = function (e) {
        var me = this;
        me.$txtMonth.removeClass('editor');
        var month = parseInt(me.$txtMonth.val());
        if (!month || month > 12) {
            month = me.showingMonth.getMonth() + 1;
            me.$txtMonth.val(month);
        }
        if (month - 1 != me.showingMonth.getMonth()) {
            me.showMonth(me.showingMonth.getFullYear(), month - 1);
        }
    };

    proto.onTxtMonthMouseDown = function (e) {
        var me = this;
        if (me.$txtMonth.hasClass('editor')) {
            return;
        }
        e.preventDefault();
        me.$txtMonth.focus();
        me.$txtMonth.selectGrid({
            items: monthAbbrs,
            colCount: 2,
            colFirst: true,
            selectedCallback: function (value) {
                me.$txtMonth.val(jsex.indexOf(monthAbbrs, value) + 1).trigger('blur');
            }
        });
    };

    //
    proto.onTxtYearBlur = function (e) {
        var me = this;
        me.$txtYear.removeClass('editor');
        domex.clearSelection(me.$txtYear[0]);

        var year = parseInt(me.$txtYear.val());
        if (!year || year > 2099 || year < 1900) {
            year = me.showingMonth.getFullYear();
            me.$txtYear.val(year);
        }
        if (year != me.showingMonth.getFullYear()) {
            me.showMonth(year);
        }
    };

    proto.onTxtYearMouseDown = function (e) {
        var me = this;
        if (me.$txtYear.hasClass('editor')) {
            return;
        }
        e.preventDefault();
        me.$txtYear.focus();
        var years = [];
        var year = me.showingMonth.getFullYear();
        var startOffset = Math.min(-5, year - 1900);
        for (var n = 0; n < 10; n++) {
            years.push(year + startOffset + n);
        }
        me.$txtYear.selectGrid({
            items: years,
            itemRenderer: function (item) {
                if (item < 1900 || item > 2099) {
                    return '<td class="disabled">' + item + '</td>';
                }
            },
            colCount: 2,
            colFirst: true,
            selectedCallback: function (value) {
                me.$txtYear.val(value).trigger('blur');
            }
        });
        me.setupYearSelectGridPager(me.$txtYear.selectGrid('getContainer'), years);
    };

    proto.setupYearSelectGridPager = function (selectGridContainer, years) {
        var me = this;
        var $sgc = $(selectGridContainer);//$('.selectGridContainer:visible');
        var $pager = $('<div class="yearPager"><table><tr>' +
            '<td><a href="javascript:void(0);" class="pageup">←</a></td>' +
            '<td><a href="javascript:void(0);" class="close">×</a></td>' +
            '<td><a href="javascript:void(0);" class="pagedown">→</a></td>' +
            '</tr></div>');
        $pager.appendTo($sgc);
        me.updateYearPageButtonStates($pager, years);
        $pager.find('.pageup').on('mousedown',function (e) {
            me.$txtYear.focus();
            years = me.onYearPageButtonMouseDown(e, this, years, -1);
        }).on('focus', function (e) {
                e.preventDefault();
                me.$txtYear.focus();

            });
        $pager.find('.pagedown').on('mousedown',function (e) {
            years = me.onYearPageButtonMouseDown(e, this, years, 1);
        }).on('focus', function (e) {
                e.preventDefault();
                me.$txtYear.focus();

            });
        $pager.find('.close').on('mousedown', function (e) {
            me.$txtYear.blur().selectGrid('hide');
            e.stopPropagation();
        });
    };

    proto.updateYearPageButtonStates = function ($pager, years) {
        var me = this;
        $pager.find('.pageup').parent().toggleClass('disabled', years[0] <= 1900);
        $pager.find('.pagedown').parent().toggleClass('disabled', years[9] >= 2099);
    };

    // direction = +1/-1
    proto.onYearPageButtonMouseDown = function (e, button, years, direction) {
        var me = this;
        e.preventDefault();
        if ($(button).parent().hasClass('disabled')) {
            return years;
        }
        var newYears = [];
        for (var n = 0; n < 10; ++n) {
            var year = years[n] + direction * 10;
            newYears.push(year);
        }
        me.$txtYear.selectGrid('setItems', newYears);
        var $pager = $(button).parents('.yearPager');
        me.updateYearPageButtonStates($pager, newYears);
        return newYears;
    };

    //
    proto.onDayClick = function ($td) {
        var me = this;

        var selectedDate = new Date(me.showingMonth.getTime());
        var dayOfMonth = parseInt($td.text());
        selectedDate.setDate(dayOfMonth);
        me.selectedDate = selectedDate;

        var toShowMonth = me.showingMonth;
        if ($td.hasClass('prev_month')) {
            toShowMonth = new Date(me.showingMonth.getFullYear(), me.showingMonth.getMonth() - 1, 1);
        }
        else if ($td.hasClass('next_month')) {
            toShowMonth = new Date(me.showingMonth.getFullYear(), me.showingMonth.getMonth() + 1, 1);
        }
        if (toShowMonth != me.showingMonth) {
            me.selectedDate = new Date(toShowMonth.getTime());
            me.selectedDate.setDate(dayOfMonth);
            me.showMonth(toShowMonth);
        }
        else {
            me.$table.find('tbody.days td.selected').removeClass('selected');
            $td.addClass('selected');
        }

        //
        if(!me.$timePicker) {
            me.$container.find('.btnOk').trigger('click');
        }
    };

    proto.showMonth = function (year, month) {
        var me = this;

        var monthDate;
        if (typeof(year) == 'object') {
            monthDate = year;
        }
        else {
            if (typeof(month) == 'undefined') {
                month = me.showingMonth.getMonth();
            }
            monthDate = new Date(year, month, 1);
        }
        me.showingMonth = monthDate;
        me.render();
    };

    //
    proto.render = function () {
        var me = this;

        var year = me.showingMonth.getFullYear();
        var month = me.showingMonth.getMonth();

        var month_1st = new Date(year, month, 1);
        var month_last = new Date(year, month + 1, 0);

        var dayOfWeek = month_1st.getDay();
        var cal_1st = new Date(year, month, 1 - (dayOfWeek == 0 ? 7 : dayOfWeek));

        var $tbody = me.$table.find('tbody.days');

        var selectedDay = new Date(me.selectedDate.getFullYear(),
            me.selectedDate.getMonth(),
            me.selectedDate.getDate());

        var n;
        var html = '';
        var day = new Date(cal_1st.getTime());
        for (var w = 1; w <= 6; ++w) {
            html += '<tr>';
            for (var d = 0; d < 7; ++d) {
                var date = day.getDate();
                var clazz = '';
                if (day < month_1st) {
                    clazz = 'prev_month sibling_month';
                }
                else if (day > month_last) {
                    clazz = 'next_month sibling_month';
                }
                else {
                    clazz = 'this_month';
                    if (d == 0 || d == 6) {
                        clazz += ' weekend';
                    }
                    else {
                        clazz += ' weekday';
                    }
                }
                if (day - selectedDay == 0) {
                    clazz += ' selected';
                }
                html += '<td class="' + clazz + '">' + date + '</td>';
                day.setDate(date + 1);
            }
            html += '</tr>';
        }
        $tbody.html(html);

        me.$txtMonth.val('' + (month + 1));
        me.$txtYear.val('' + year);

    };

    proto.setValue = function (value) {
        var me = this;
        var type = $.type(value);
        if (type == 'date') {
            //
        }
        else if (type == 'number') {
            value = new Date(value);
        }
        else {
            value = jsex.parseDate(value);
        }
        me.value = value;
        me.selectedDate = value || new Date();

        //
        me.$txtYear.val(me.selectedDate.getFullYear());
        me.$txtMonth.val(me.selectedDate.getMonth() + 1);

        //
        if (me.$timePicker) {
            me.$timePicker.timePicker('setValue', me.selectedDate);
        }

        me.showMonth(me.selectedDate.getFullYear(), me.selectedDate.getMonth());
    };

    proto.getValue = function () {
        var me = this;
        var date = new Date(me.selectedDate.getTime());
        if (me.$timePicker) {
            var time = me.$timePicker.timePicker('getValue');
            date.setHours(time.getHours(), time.getMinutes(), time.getSeconds());
        }
        return date;
    };

    $.fn.datetimePicker = $.addPluginFn('datetimePicker', DatetimePicker, {
        debug: true,
        precision: 'second'
    });

    $.fn.datetimePicker.setMonthAbbrs = function(abbrs) {
        monthAbbrs = abbrs;
    };

})(jQuery);